home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xgrabsc / write.hc < prev    next >
Text File  |  1995-05-09  |  43KB  |  1,444 lines

  1. /*========================================================================
  2.  *
  3.  * Name - write.hc
  4.  *
  5.  * ccs version:    1.16
  6.  *
  7.  * ccsid:    @(#)write.hc    1.16 - 06/28/93 09:13:46
  8.  * from:     ccs/s.write.hc
  9.  * date:     06/28/93 09:14:49
  10.  *
  11.  * Description:  output conversions for xgrabsc
  12.  *
  13.  *               see cpyright.h for copyright information
  14.  *
  15.  *
  16.  *========================================================================
  17.  */
  18.  
  19.  
  20. /* swap the bits in a byte */
  21. swapbits(b)
  22.   byte b;
  23. {
  24.   byte b2;
  25.  
  26.   b2 = 0;
  27.   b2 |= (b & 0x01) << 7;
  28.   b2 |= (b & 0x02) << 5;
  29.   b2 |= (b & 0x04) << 3;
  30.   b2 |= (b & 0x08) << 1;
  31.   b2 |= (b & 0x10) >> 1;
  32.   b2 |= (b & 0x20) >> 3;
  33.   b2 |= (b & 0x40) >> 5;
  34.   b2 |= (b & 0x80) >> 7;
  35.   return b2;
  36. }
  37.  
  38.  
  39.  
  40.  
  41. /* swap the bytes in a long int */
  42. swapbytes(pDblw)
  43.   dw *pDblw;
  44.   {
  45.   union {
  46.     dw  dbl;
  47.     byte bytes[4];
  48.     } cnv;
  49.   byte aByte;
  50.  
  51.   cnv.dbl = *pDblw;
  52.   aByte = cnv.bytes[0];
  53.   cnv.bytes[0] = cnv.bytes[3];
  54.   cnv.bytes[3] = aByte;
  55.   aByte = cnv.bytes[1];
  56.   cnv.bytes[1] = cnv.bytes[2];
  57.   cnv.bytes[2] = aByte;
  58.   *pDblw = cnv.dbl;
  59.   }
  60.  
  61.  
  62.  
  63. /* swap some long ints.  (n is number of BYTES, not number of longs) */
  64. swapdws (bp, n)
  65.   register char *bp;
  66.   register unsigned n;
  67. {
  68.   register char c;
  69.   register char *ep = bp + n;
  70.   register char *sp;
  71.  
  72.   while (bp < ep) {
  73.     sp = bp + 3;
  74.     c = *sp;
  75.     *sp = *bp;
  76.     *bp++ = c;
  77.     sp = bp + 1;
  78.     c = *sp;
  79.     *sp = *bp;
  80.     *bp++ = c;
  81.     bp += 2;
  82.   }
  83. }
  84.  
  85.  
  86.  
  87. /* swap some short ints */
  88. swapwords (bp, n)
  89.   register char *bp;
  90.   register unsigned n;
  91. {
  92.   register char c;
  93.   register char *ep = bp + n;
  94.  
  95.   while (bp < ep) {
  96.     c = *bp;
  97.     *bp = *(bp + 1);
  98.     bp++;
  99.     *bp++ = c;
  100.   }
  101. }
  102.  
  103.  
  104.  
  105.  
  106.  
  107. writeSimple(image, outfile)
  108.   imageInfo *image;
  109.   FILE *outfile;
  110. {
  111.   dw width, height, hasColormap, colormapSize;
  112.   dw swaptest = 1;
  113.   int i, w, h;
  114.  
  115.   if (verbose)
  116.     fprintf(stderr, "%s: writing in simple output format\n", programName);
  117.   if (image->ximage->depth != 8) {
  118.     fprintf(stderr, "%s: can't write simple image format if depth is not 8\n",
  119.             programName);
  120.     return;
  121.   }
  122.   width        = image->ximage->width;
  123.   height       = image->ximage->height;
  124.   hasColormap  = 1;
  125.   colormapSize = image->numcells;
  126.   if (*(char *)&swaptest==0) {
  127.     swapdws(&width,        1);
  128.     swapdws(&height,       1);
  129.     swapdws(&hasColormap,  1);
  130.     swapdws(&colormapSize, 1);
  131.   }
  132.   fwrite(&width, 4, 1, outfile);
  133.   fwrite(&height, 4, 1, outfile);
  134.   fwrite(&hasColormap, 4, 1, outfile);
  135.   fwrite(&colormapSize, 4, 1, outfile);
  136.   for (i=0; i<image->numcells; i++)
  137.     fputc((byte)(image->red[i]>>8), outfile);
  138.   for (i=0; i<image->numcells; i++)
  139.     fputc((byte)(image->green[i]>>8), outfile);
  140.   for (i=0; i<image->numcells; i++)
  141.     fputc((byte)(image->blue[i]>>8), outfile);
  142.   for (i=0; i<image->numcells; i++)
  143.     fputc((byte)(image->used[i]), outfile);
  144.   for (h=0; h<image->ximage->height; h++)
  145.     for (w=0; w<image->ximage->width; w++)
  146.       fputc(XGetPixel(image->ximage, w, h), outfile);
  147. }
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155. /*
  156.  * makePSImage returns an XImage structure that contains the samples
  157.  * to be written.  If the input image is monochrome, its XImage structure
  158.  * will be returned.  Otherwise a new structure is allocated and returned.
  159.  */
  160.  
  161. XImage* makePSImage(image, desiredDepth, depth, bpl, spb)
  162.     imageInfo* image;
  163.     int desiredDepth;  /* 0 = don't care */
  164.     int* depth;
  165.     int* bpl;
  166.     int* spb;
  167. {
  168.     register byte* ptr;
  169.     int lshift, lmask;
  170.     long p;
  171.     int x, y, i;
  172.     XImage* ximage = image->ximage;
  173.     XImage* psimage;
  174.  
  175.   /* use depth as the number of bits in output samples */
  176.   *depth = ximage->depth;
  177.   /* postscript only supports 1, 2, 4, or 8 */
  178.   if (*depth > 8) *depth = 8;     /* max postscript bits/sample */
  179.   if (*depth < 8 && *depth > 4) *depth = 8;
  180.   if (*depth == 3) *depth = 4;
  181.     
  182.     if (desiredDepth == 0) {
  183.     desiredDepth = *depth;
  184.     }
  185.  
  186.  
  187.   *bpl = ((ximage->width * desiredDepth) + 7) / 8;
  188.  
  189.   if (*depth == 1)
  190.     /* Same image */
  191.     psimage = ximage;
  192.   else {
  193.     /* colors have to be changed to luminescence */
  194.     ptr = (byte *)malloc(ximage->height * *bpl);
  195.     psimage = XCreateImage(hDisplay, DefaultVisual(hDisplay, hScreen),
  196.                   desiredDepth, ZPixmap,
  197.                   0, ptr,
  198.                   ximage->width, ximage->height,
  199.                   8, *bpl);
  200.     if (!psimage) {
  201.       fprintf(stderr, "%s: could not create image for Postscript conversion\n",
  202.         programName);
  203.       exit(3);
  204.     }
  205.     /* force the bits_per_pixel to be what is needed */
  206.     psimage->bits_per_pixel = desiredDepth;
  207.   }
  208.  
  209.   *spb = 8 / psimage->bits_per_pixel;    /* samples per byte */
  210.  
  211.   if (*depth > 1) {
  212.     /* translate colors into grays */
  213.     lshift = 16 - psimage->bits_per_pixel;
  214.     lmask  = (1 << psimage->bits_per_pixel) - 1;
  215.     for (y = 0; y < ximage->height; y++) {
  216.       for (x = 0; x < ximage->width; x++) {
  217.         p = XGetPixel(ximage, x, y);
  218.         i = (0.30*(double)image->red[p]) +
  219.             (0.59*(double)image->green[p])+
  220.             (0.11*(double)image->blue[p]);
  221.         i = (i >> lshift) & lmask;
  222.         XPutPixel(psimage, x, y, i);
  223.       }
  224.     }
  225.   }
  226.   *depth = desiredDepth;  /* The final resolution */
  227.   return psimage;
  228. }
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236. writeOnlyPreview(image, outfile)
  237.   imageInfo *image;
  238.   FILE* outfile;
  239. {
  240.   XImage* psimage = (XImage *) NULL;
  241.  
  242.   if (verbose) fprintf(stderr, "%s: generating only EPSI preview comment\n", programName);
  243.  
  244.   if (image->ximage->depth == 1) {
  245.     /* First process the image to make it good */
  246.     int depth, bpl, spb;
  247.     psimage = makePSImage(image, 1, &depth, &bpl, &spb);
  248.   }
  249.  
  250.   writePreview(image, outfile, psimage);
  251.  
  252.   if (psimage && psimage != image->ximage) {
  253.     /* Free the allocated PostScript image */
  254.     free(psimage->data);
  255.     free(psimage);
  256.   }
  257. }
  258.  
  259.  
  260.  
  261. writePreview(image, outfile, defaultImage)
  262.   imageInfo *image;
  263.   XImage *defaultImage;
  264.   FILE *outfile;
  265. {
  266.   register byte b, *ptr;
  267.   int depth, bpl, spb;
  268.   int reverse, x, y;
  269.   int widthcount, lines;
  270.   XImage* ximage = image->ximage;
  271.   XImage* psimage = (XImage *)NULL;
  272.   imageInfo newImage;
  273.     
  274.   newImage.ximage = (XImage*) NULL;
  275.       
  276.   if (ximage->depth > 1) {
  277.     /* Copy the image before doing any changes! */
  278.     int i;
  279.     for (i = 0; i < image->numcells; ++i) {
  280.     newImage.red[i] = image->red[i];
  281.         newImage.green[i] = image->green[i];
  282.         newImage.blue[i] = image->blue[i];
  283.         newImage.used[i] = image->used[i];
  284.     }
  285.     newImage.numcells = image->numcells;
  286.     newImage.ximage = XSubImage(ximage, 0, 0, ximage->width, ximage->height);
  287.     if (!newImage.ximage) {
  288.       fprintf(stderr, "%s: unable to create copy of color image\n",
  289.         programName);
  290.       XCloseDisplay(hDisplay);
  291.       exit(3);
  292.     }
  293.  
  294.     if (ForceBitmap)
  295.       pixmap2bitmap(&newImage);
  296.     else if (Halftone)
  297.       pixmap2halftone(&newImage, DitherKind);
  298.     else
  299.       pixmap2halftone(&newImage, FS_DITHER);
  300.  
  301.     defaultImage = newImage.ximage;
  302.     image = &newImage;
  303.     psimage = makePSImage(&newImage, 1, &depth, &bpl, &spb);
  304.   }
  305.   else {
  306.     /* the image is already monochrome, so use the psimage that's already
  307.      * been processed */
  308.     psimage = defaultImage;
  309.     bpl = (psimage->width + 7) / 8;
  310.     spb = 8;
  311.   }
  312.     
  313.  
  314.   /* compute the number of lines in the preview output so
  315.    * apps reading the file can easily skip it */
  316.   lines = (bpl * psimage->height) / (PREVIEW_CODEWIDTH / 2);
  317.   if ((bpl * psimage->height) % (PREVIEW_CODEWIDTH / 2) > 0) lines++;
  318.  
  319.   fprintf(outfile, "%%%%BeginPreview: %d %d %d %d\n%%",
  320.         psimage->width, psimage->height, psimage->depth, lines);
  321.  
  322.     
  323.   /* if the bits haven't been swizzled yet, we have to check for color
  324.    * reversal */
  325.   if (psimage == image->ximage)
  326.     reverse = BlackPixel(hDisplay,hScreen)!=EPSF_BLACK;
  327.   else
  328.     reverse = FALSE;
  329.  
  330.   widthcount = 0;
  331.   for (y=0; y<psimage->height; y++) {
  332.     /* note that depth 1 images are already padded to even byte boundaries
  333.      * under X, so there is no need to shift bits around to do padding of
  334.      * the preview image */
  335.     for (x=0, ptr=(byte *)(psimage->data+(y * psimage->bytes_per_line));
  336.          x<psimage->width;
  337.          x+=spb, ptr++) {
  338.       b = *ptr;
  339.       if (reverse) b = ~b;
  340.       if (depth == 1  &&  psimage->bitmap_bit_order == LSBFirst)
  341.         b = swapbits(b);
  342.       fprintf(outfile, "%02.2x", b);
  343.       widthcount += 2;
  344.       if (widthcount >= PREVIEW_CODEWIDTH) {
  345.     fputs("\n%", outfile);
  346.         widthcount = 0;
  347.       }
  348.     }
  349.   }
  350.  
  351.   if (widthcount == 0)
  352.     fputs("%EndPreview\n", outfile);
  353.   else
  354.     fputs("\n%%EndPreview\n", outfile);
  355.     
  356.   if (psimage && psimage != defaultImage) {
  357.     free(psimage->data);
  358.     free(psimage);
  359.   }
  360.   if (newImage.ximage) {
  361.     XDestroyImage(newImage.ximage);
  362.   }
  363. }
  364.  
  365.  
  366.  
  367. /*
  368.  * Write an image in Postscript format
  369.  */
  370. writePostscript(image, outfile, encode, encapsulate, preview,
  371.   landscape, binary, checkLimits)
  372.   imageInfo *image;
  373.   FILE *outfile;
  374.   int encode;       /* TRUE if we're to encode the Postscript output */
  375.   int encapsulate;  /* TRUE if encapsulated Postscript output is wanted */
  376.   int preview;      /* TRUE if EPSI preview image is to be written with EPS output */
  377.   int landscape;    /* TRUE if landscape format is wanted */
  378.   int binary;       /* TRUE if binary output is wanted */
  379.   int checkLimits;  /* TRUE if PS interpreter memory checks should be made */
  380. {
  381.   register byte b, *ptr;
  382.   register int x, y;
  383.   register int i;
  384.   XImage *ximage = image->ximage;
  385.   XImage *psimage;
  386.   double xdpi, ydpi, xscale, yscale, f;
  387.   int lshift, lmask;
  388.   int depth, bpl, spb;
  389.   int reverse;
  390.   long p;
  391.   /* rle variables */
  392.   int rlecount;
  393.   byte rlesample;
  394.   dw  rletotal;
  395.   int widthcount;
  396.   int firstSample;
  397.  
  398.   if (verbose)
  399.     fprintf(stderr, "%s: formatting Postscript output\n", programName);
  400.  
  401.   if (preview)
  402.     encapsulate = TRUE;
  403.  
  404.   if (encapsulate)
  405.     landscape = FALSE;  /* landscape uses a transformation matrix */
  406.  
  407.   psimage = makePSImage(image, 0, &depth, &bpl, &spb);
  408.  
  409. #ifndef NO_RLE_CHECKS
  410.   if (encode) {
  411.     rletotal = 0;
  412.     rlecount = 0;
  413.     firstSample = TRUE;
  414.     for (y=0; y<psimage->height; y++)
  415.       for (x=0, ptr=(byte *)(psimage->data + (y * psimage->bytes_per_line));
  416.            x<psimage->width; x+=spb, ptr++) {
  417.         b = *ptr;
  418.     if (firstSample || b != rlesample || rlecount==254) {
  419.       if (!firstSample)
  420.         rletotal += 2;
  421.       else
  422.         firstSample = FALSE;
  423.       rlecount = 0;
  424.       rlesample = b;
  425.     }
  426.     else
  427.       rlecount++;
  428.       }
  429.     if (!firstSample)
  430.       rletotal += 2;
  431.     f = (float)(rletotal) / (float)(psimage->height*bpl);
  432.     if (verbose)
  433.       fprintf(stderr, "%s: encoding would change to %5.1f%% of orig size\n",
  434.             programName, f * 100.0);
  435.     encode = f <= 0.95;
  436.   }
  437. #endif
  438.  
  439.  
  440.  
  441.   if (verbose)
  442.     fprintf(stderr, "%s: image will %sbe encoded\n", programName,
  443.             encode? "" : "not ");
  444.  
  445.   if (encapsulate) {
  446.     fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  447.     fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
  448.                 0, 0, psimage->width, psimage->height);
  449.   }
  450.   else
  451.     fprintf(outfile, "%%!PS-Adobe-2.0\n");
  452.  
  453.   fprintf(outfile, "%%%%Creator: xgrabsc\n");
  454.   fprintf(outfile, "%%%%Title: %s\n", imageName);
  455.   if (outfileName)
  456.     fprintf(outfile, "%%%%File: %s\n", outfileName);
  457.   time(&p);
  458.   fprintf(outfile, "%%%%CreationDate: %s", ctime(&p));
  459.   fprintf(outfile, "%%%%EndComments\n");
  460.   fprintf(outfile, "%%\n");
  461.   fprintf(outfile, "%%\n");
  462.  
  463.   /* if the user wants a preview image, EPS 2.0 says it must go here */
  464.   if (preview)
  465.     writePreview(image, outfile, psimage);
  466.  
  467.  
  468.   fprintf(outfile, "%%%%EndProlog\n");
  469.   if (encapsulate) {
  470.     fprintf(outfile, "%%%%Page: 1 1\n");
  471.   }
  472.  
  473.   /* standard inch procedure */
  474.   fputs("/inch {72 mul} def\n", outfile);
  475.  
  476.  
  477.   /* define a string to hold image bytes */
  478.   if (encode) {
  479.     fputs("/rlebuffer 2 string def\n", outfile);
  480.     fprintf(outfile, "/samples %d string def\n", 256);  /* max bytes per burst */
  481.   }
  482.   else
  483.     fprintf(outfile, "/picstr %d string def\n", bpl);
  484.  
  485.   if (binary) {
  486.     fputs("/endstr 1 string def\n", outfile);
  487.     if (encode) fputs("/ccount 0 def\n", outfile);
  488.   }
  489.  
  490.   /* define the image plotting procedure */
  491.   fputs("/plotimage\n", outfile);
  492.  
  493.   fprintf(outfile, "{%d %d %d ",
  494.         psimage->width, psimage->height, psimage->bits_per_pixel);
  495.  
  496.  
  497.  
  498.   /* transformation matrix */
  499.   if (landscape)
  500.     fprintf(outfile, "[0 %d %d 0 0 0]\n", psimage->width, psimage->height);
  501.   else
  502.     fprintf(outfile, "[%d 0 0 -%d 0 %d]\n",
  503.         psimage->width, psimage->height, psimage->height);
  504.  
  505.   /* line reading function  */
  506.  
  507.   if (encode) {
  508.     fputs("% run-length decoding block\n",                                       outfile);
  509.     if (binary) {
  510.       fputs("  { currentfile rlebuffer readstring pop pop\n", outfile);
  511.       fputs("    /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  512.       fprintf(outfile,
  513.             "    ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  514.       fputs("    { /ccount 0 def                          %% reset character counter\n",outfile);
  515.       fputs("      currentfile endstr readline pop pop    %% skip newline\n",outfile);
  516.       fputs("    } if                                     %% skip newlines after full line\n",outfile);
  517.     }
  518.     else
  519.       fputs("  { currentfile rlebuffer readhexstring pop pop\n",                 outfile);
  520.     fputs("    rlebuffer 0 get 1 add       %% number of copies of the sample\n", outfile);
  521.     fputs("    /nsamples exch store        %% save it away\n",                   outfile);
  522.     fputs("    /lum rlebuffer 1 get store  %% the sample itself\n",              outfile);
  523.     fputs("    0 1 nsamples 1 sub { samples exch lum put } for\n",               outfile);
  524.     fputs("    samples 0 nsamples getinterval %% leave the pixels on the stack\n",outfile);
  525.     fputs("  }\n", outfile);
  526.   }
  527.   else {
  528.     if (binary) {
  529.       /* Do a "readline" after each "readstring" so we can seperate each
  530.          scanline of binary data with a "newline" */
  531.       fputs("   {currentfile picstr readstring pop\n", outfile);
  532.       fputs("    currentfile endstr readline pop pop}\n", outfile);
  533.     }
  534.     else
  535.       fputs("  {currentfile picstr readhexstring pop}\n", outfile);
  536.   }
  537.  
  538.   fputs("  image\n} def\n", outfile);
  539.  
  540.  
  541.   /* emit some code to check for resource availability */
  542.   if (!encapsulate  &&  checkLimits) {
  543.     for (x=0; CheckVM[x] != NULL; x++) {
  544.       fputs(CheckVM[x], outfile);
  545.       fputc('\n', outfile);
  546.     }
  547.     fprintf(outfile, "\n\n");
  548.     fprintf(outfile, "%d checkvm\n", psimage->height * bpl);
  549.   }
  550.  
  551.   /* save context and move to a nice origin */
  552.   fputs("gsave\n", outfile);
  553.  
  554.   if (encapsulate) {
  555.     /* for encapsulated postscript, we need a scale factor that is equal
  556.      * to the image width/height in samples */
  557.     fprintf(outfile, "%d %d scale\n", psimage->width, psimage->height);
  558.   }
  559.   else {
  560.     /* For physical output we need a scale factor that will create
  561.       * the same size image, and we need to center it on the page.
  562.       *   -Figure out the physical dimensions on the screen
  563.       *    and make it come out the same on the printer. */
  564.     xdpi = (((double)DisplayWidth(hDisplay,hScreen)) * 25.4) /
  565.             ((double)DisplayWidthMM(hDisplay,hScreen));
  566.     ydpi = (((double)DisplayHeight(hDisplay,hScreen)) * 25.4) /
  567.             ((double)DisplayHeightMM(hDisplay,hScreen));
  568.     xscale = ((double)psimage->width) / xdpi;
  569.     yscale = ((double)psimage->height) / ydpi;
  570.     if (landscape) {
  571.       f = xscale; xscale = yscale; yscale = f;
  572.     }
  573.     if (xscale > horizInset) {
  574.       yscale *= horizInset / xscale;
  575.       xscale = horizInset;
  576.     }
  577.     if (yscale > vertInset) {
  578.       xscale *= vertInset / yscale;
  579.       yscale = vertInset;
  580.     }
  581.     fprintf(outfile, "%1.2g inch %1.2g inch translate\n",
  582.                   (pageWidth - xscale) / 2.0, (pageHeight - yscale) / 2.0);
  583.     if (landscape)
  584.       fprintf(outfile, "%1.2g inch %1.2g inch scale\n", yscale, xscale);
  585.     else
  586.       fprintf(outfile, "%1.2g inch %1.2g inch scale\n", xscale, yscale);
  587.   }
  588.  
  589.  
  590.  
  591.   if (binary)
  592.     fprintf(outfile,"%%%%BeginBinary: %d\n",
  593.         encode ? rletotal+11+rletotal/IMAGE_CODEWIDTH
  594.         : ximage->height*(ximage->width+1)+10);
  595.  
  596.   fputs("plotimage\n", outfile);
  597.  
  598.  
  599.   reverse = depth == 1? BlackPixel(hDisplay,hScreen)==1 : FALSE;
  600.   if (encode) {
  601.     rletotal = 0;
  602.     rlecount = 0;
  603.     firstSample = TRUE;
  604.   }
  605.   widthcount = 0;
  606.   for (y=0; y<psimage->height; y++) {
  607.     for (x=0, ptr=(byte *)(psimage->data+(y * psimage->bytes_per_line));
  608.          x<psimage->width;
  609.          x+=spb, ptr++) {
  610.       b = *ptr;
  611.       if (reverse) b = ~b;
  612.       if (depth == 1  &&  psimage->bitmap_bit_order == LSBFirst)
  613.         b = swapbits(b);
  614.       if (encode) {
  615.         if (firstSample || b != rlesample || rlecount==254) {
  616.       if (!firstSample) {
  617.         if (binary) {
  618.           putc((byte)rlecount,outfile);
  619.           putc((byte)rlesample,outfile);
  620.           widthcount += 2;
  621.         }
  622.         else {
  623.           fprintf(outfile, "%02.2x%02.2x", rlecount, rlesample);
  624.           widthcount += 4;
  625.         }
  626.         rletotal += 2;
  627.         if (widthcount >= IMAGE_CODEWIDTH) {
  628.           fputc('\n', outfile);
  629.           widthcount = 0;
  630.         }
  631.       }
  632.       else
  633.         firstSample = FALSE;
  634.       rlecount = 0;
  635.       rlesample = b;
  636.     }
  637.     else
  638.       rlecount++;
  639.       }
  640.       else {
  641.     if (binary)
  642.       putc((byte)b,outfile);
  643.     else {
  644.           fprintf(outfile, "%02.2x", b);
  645.       widthcount += 2;
  646.       if (widthcount >= IMAGE_CODEWIDTH) {
  647.         fputc('\n', outfile);
  648.             widthcount = 0;
  649.           }
  650.         }
  651.       }
  652.     }
  653.     if (binary && !encode) putc('\n',outfile);
  654.   }
  655.  
  656.   if (encode) {
  657.     if (!firstSample) {
  658.       if (binary) {
  659.     putc((byte)rlecount,outfile);
  660.     putc((byte)rlesample,outfile);
  661.       }
  662.       else
  663.         fprintf(outfile, "%02.2x%02.2x\n", rlecount, rlesample);
  664.       rletotal += 2;
  665.     }
  666.     putc('\n',outfile);
  667.     if (binary) fputs("%%EndBinary\n",outfile);
  668.     fputs("%\n", outfile);
  669.     fprintf(outfile, "%% Run-length encoding savings = %5.1f%%\n",
  670.           100.0 - ((float)(rletotal) * 100.0 / (float)(psimage->height * bpl)));
  671.     fputs("%\n", outfile);
  672.   }
  673.   else if (binary) fputs("%%EndBinary\n",outfile);
  674.  
  675.   fputs("\n\n\ngrestore\nshowpage\n", outfile);
  676.   fputs("\n%%Trailer\n", outfile);
  677.  
  678.  
  679.   if (psimage != ximage) {
  680.     free(psimage->data);
  681.     free(psimage);
  682.   }
  683. }
  684.  
  685.  
  686.  
  687.  
  688.  
  689. /*
  690.  * Write an image in Color Postscript format
  691.  */
  692. writeColorPS(image, outfile, encode, encapsulate, preview,
  693.   landscape, binary, checkLimits)
  694.   imageInfo *image;
  695.   FILE *outfile;
  696.   int encode;       /* TRUE if we're to encode the Postscript output    */
  697.   int encapsulate;  /* TRUE if encapsulated Postscript output is wanted */
  698.   int preview;      /* TRUE if EPSI preview image is to be written with EPS output */
  699.   int landscape;    /* TRUE if landscape output is wanted               */
  700.   int binary;       /* TRUE if binary Postscript output is wanted */
  701.   int checkLimits;  /* TRUE if PS interpreter memory checks should be made */
  702. {
  703.   register byte *ptr, b;
  704.   register int x, y;
  705.   XImage *ximage = image->ximage;
  706.   double xdpi, ydpi, xscale, yscale, f;
  707.   double left, top;
  708.   int depth, bpl, spb;
  709.   long p;
  710.   /* rle variables */
  711.   int rlecount;
  712.   dw  rletotal;
  713.   byte rlesample;
  714.   int firstSample;
  715.   int widthcount;
  716.  
  717.  
  718.   if (verbose)
  719.     fprintf(stderr, "%s: formatting Color Postscript output\n", programName);
  720.  
  721.   if (preview)
  722.     encapsulate = TRUE;  /* should have been enforced before this point */
  723.  
  724.   if (encapsulate)
  725.     landscape = FALSE;  /* landscape uses a transformation matrix */
  726.  
  727.   depth = 8;                                  /* bits per sample  */
  728.   spb   = 1;                                  /* samples per byte */
  729.   bpl = ((ximage->width * depth) + 7) / 8;    /* bytes per line   */
  730.  
  731.  
  732. #ifndef NO_RLE_CHECKS
  733.   if (encode) {
  734.     rletotal = 0;
  735.     rlecount = 0;
  736.     firstSample = TRUE;
  737.     for (y=0; y<ximage->height; y++)
  738.       for (x=0, ptr=(byte *)(ximage->data + (y * ximage->bytes_per_line));
  739.            x<ximage->width; x+=spb, ptr++) {
  740.         b = *ptr;
  741.     if (firstSample || b != rlesample || rlecount==254) {
  742.       if (!firstSample)
  743.         rletotal += 2;
  744.       else
  745.         firstSample = FALSE;
  746.       rlecount = 0;
  747.       rlesample = b;
  748.     }
  749.     else
  750.       rlecount++;
  751.       }
  752.     rletotal += 2;
  753.     f = (float)(rletotal) / (float)(ximage->height*bpl);
  754.     if (verbose)
  755.       fprintf(stderr, "%s: encoding would change to %5.1f%% of orig size\n",
  756.             programName, f * 100.0);
  757.     encode = f <= 0.95;
  758.   }
  759. #endif
  760.  
  761.   if (encapsulate) {
  762.     fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  763.   }
  764.   else
  765.     fprintf(outfile, "%%!PS-Adobe-2.0\n");
  766.  
  767.   fprintf(outfile, "%%%%Creator: xgrabsc\n");
  768.   fprintf(outfile, "%%%%Title: %s\n", imageName);
  769.   if (outfileName)
  770.     fprintf(outfile, "%%%%File: %s\n", outfileName);
  771.   if (encapsulate) {
  772.     fprintf(outfile, "%%%%Pages: 1\n");
  773.     fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
  774.                 0, 0, ximage->width, ximage->height);
  775.   }
  776.   time(&p);
  777.   fprintf(outfile, "%%%%CreationDate: %s", ctime(&p));
  778.   fprintf(outfile, "%%%%EndComments\n");
  779.  
  780.   /* if the user wants a preview image, EPS 2.0 says it must go here */
  781.   if (preview)
  782.     writePreview(image, outfile, image->ximage);
  783.  
  784.   fprintf(outfile, "%%%%EndProlog\n");
  785.   if (encapsulate) {
  786.     fprintf(outfile, "%%%%Page: 1 1\n");
  787.   }
  788.   fprintf(outfile, "\n\ngsave\n\n");
  789.  
  790.  
  791.   fputs("/inch {72 mul} def\n", outfile);
  792.  
  793.   /* emit some code to check for resource availability */
  794.   if (!encapsulate  &&  checkLimits) {
  795.     for (x=0; CheckVM[x] != NULL; x++) {
  796.       fputs(CheckVM[x], outfile);
  797.       fputc('\n', outfile);
  798.     }
  799.     fprintf(outfile, "\n\n");
  800.     fprintf(outfile, "%d checkvm\n\n", ximage->height * bpl);
  801.   }
  802.  
  803.   if (encapsulate) {
  804.     /* don't translate the image for encapsulated postscript.  The
  805.      * scale should match the data dimensions of the image in samples.  */
  806.     fprintf(outfile, "%d %d scale\n", ximage->width, ximage->height);
  807.   }
  808.   else {
  809.     /* For physical output we need a scale factor that will create
  810.      * the same size image, and we need to center it on the page.
  811.      *   -Figure out the physical dimensions on the screen
  812.      *    and make it come out the same on the printer.
  813.      */
  814.     xdpi = (((double)DisplayWidth(hDisplay,hScreen)) * 25.4) /
  815.             ((double)DisplayWidthMM(hDisplay,hScreen));
  816.     ydpi = (((double)DisplayHeight(hDisplay,hScreen)) * 25.4) /
  817.             ((double)DisplayHeightMM(hDisplay,hScreen));
  818.     xscale = ((double)ximage->width) / xdpi;
  819.     yscale = ((double)ximage->height) / ydpi;
  820.     if (landscape) {
  821.       f = xscale; xscale = yscale; yscale = f;
  822.     }
  823.     if (xscale > horizInset) {
  824.       yscale *= horizInset / xscale;
  825.       xscale = horizInset;
  826.     }
  827.     if (yscale > vertInset) {
  828.       xscale *= vertInset / yscale;
  829.       yscale = vertInset;
  830.     }
  831.      
  832.  
  833.     left = ((pageWidth - xscale) / 2.0);
  834.     top  = ((pageHeight - yscale) / 2.0);
  835.     fprintf(outfile, "%1.2g inch %1.2g inch translate\n", left, top);
  836.     if (landscape)
  837.       fprintf(outfile, "%1.2g inch %1.2g inch scale\n", yscale, xscale);
  838.     else
  839.       fprintf(outfile, "%1.2g inch %1.2g inch scale\n", xscale, yscale);
  840.     fprintf(outfile, "\n\n\n");
  841.   }
  842.  
  843.   if (binary) {
  844.     fputs("/endstr 1 string def\n", outfile);
  845.     fputs("/ccount 0 def\n", outfile);
  846.   }
  847.  
  848.   if (encode) {
  849.     /* encoded output:
  850.      * define a drawcolorimage procedure geared to this image
  851.      */
  852.     fprintf(outfile, "/rgbstr %d string def\n", 256 * 3); /* max pixels per burst */
  853.     fprintf(outfile, "/buffer %d string def\n", 2);
  854.     fputs("/rgb (000) def\n", outfile);
  855.     fprintf(outfile, "/rgbmap %d string def\n", image->numcells * 3);
  856.     fputs("/samples 256 string def\n", outfile);
  857.     fputs("\n\n", outfile);
  858.  
  859.     fputs("/drawcolormappedimage {\n", outfile);
  860.     fputs("  %% for greyscale printers, convert rgb values into grey samples\n", outfile);
  861.     fputs("  %% and use these in the 'image' operator\n", outfile);
  862.     fputs("  systemdict /colorimage known userdict /colorimage known or not {\n", outfile);
  863.     fputs("    %% convert colors to greyscale\n", outfile);
  864.     fprintf(outfile,"    /ncolors %d store\n", image->numcells);
  865.     fputs("    /ridx 0 store\n", outfile);
  866.     fputs("    /greys ncolors string def\n", outfile);
  867.     fputs("    0 1 ncolors 1 sub {\n", outfile);
  868.     fputs("      /gidx exch store\n", outfile);
  869.     fputs("      rgbmap ridx get .3 mul\n", outfile);
  870.     fputs("      rgbmap ridx 1 add get .59 mul add\n", outfile);
  871.     fputs("      rgbmap ridx 2 add get .11 mul add\n", outfile);
  872.     fputs("      cvi\n", outfile);
  873.     fputs("      /agrey exch store\n", outfile);
  874.     fputs("      greys gidx agrey put\n", outfile);
  875.     fputs("      /ridx ridx 3 add store\n", outfile);
  876.     fputs("    } for\n", outfile);
  877.     fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  878.     if (landscape)
  879.       fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  880.     else
  881.       fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  882.                                                 ximage->height);
  883.     if (binary) {
  884.       fputs("    { currentfile buffer readstring pop pop    %% run length and index\n", outfile);
  885.       fputs("      /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  886.       fprintf(outfile,
  887.             "      ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  888.       fputs("      { /ccount 0 def                          %% reset character counter\n",outfile);
  889.       fputs("        currentfile endstr readline pop pop    %% skip newline\n",outfile);
  890.       fputs("      } if                                     %% skip newlines after full line\n",outfile);
  891.     }
  892.     else
  893.       fputs("    { currentfile buffer readhexstring pop pop\n", outfile);
  894.     fputs("      buffer 0 get 1 add\n", outfile);
  895.     fputs("      /nsamples exch store\n", outfile);
  896.     fputs("      /lum greys buffer 1 get get store\n", outfile);
  897.     fputs("      0 1 nsamples 1 sub { samples exch lum put } for\n", outfile);
  898.     fputs("      samples 0 nsamples getinterval\n", outfile);
  899.     fputs("    } image\n\n", outfile);
  900.     fputs("  } {  %% ifelse\n", outfile);
  901.     fputs("\n", outfile);
  902.     fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  903.     if (landscape)
  904.       fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  905.     else
  906.       fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  907.                                                 ximage->height);
  908.     fputs("    %% define a block of code to read and decode the rle input stream\n", outfile);
  909.     if (binary) {
  910.       fputs("    { currentfile buffer readstring pop pop    %% run length and index\n", outfile);
  911.       fputs("      /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  912.       fprintf(outfile,
  913.             "      ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  914.       fputs("      { /ccount 0 def                          %% reset character counter\n",outfile);
  915.       fputs("        currentfile endstr readline pop pop    %% skip newline\n",outfile);
  916.       fputs("      } if                                     %% skip newlines after full line\n",outfile);
  917.     }
  918.     else
  919.       fputs("    { currentfile buffer readhexstring pop pop %% run length and index\n", outfile);
  920.     fputs("      /npixels buffer 0 get 1 add 3 mul store  %% number of bytes\n", outfile);
  921.     fputs("      /color buffer 1 get 3 mul store          %% fix index into rgb map\n", outfile);
  922.     fputs("      /rgb rgbmap color 3 getinterval store    %% and get the colors\n", outfile);
  923.     fputs("\n", outfile);
  924.     fputs("      0 3 npixels 1 sub {                      %% loop to store the rgb bytes\n", outfile);
  925.     fputs("        rgbstr exch rgb putinterval\n", outfile);
  926.     fputs("      } for\n", outfile);
  927.     fputs("      rgbstr 0 npixels getinterval\n", outfile);
  928.     fputs("    }\n", outfile);
  929.     fputs("    false 3 colorimage\n\n", outfile);
  930.     fputs("  } ifelse\n\n", outfile);
  931.     fputs("} bind def\n", outfile);
  932.   }
  933.  
  934.  
  935.   else {
  936.     /* non-encoded output:
  937.      * define a drawcolorimage procedure geared to this image
  938.      */
  939.     fprintf(outfile, "/buffer %d string def\n", 1);
  940.     fprintf(outfile, "/line   %d string def\n", ximage->width);
  941.     fprintf(outfile, "/rgbmap %d string def\n", image->numcells * 3);
  942.     fputs("\n\n", outfile);
  943.  
  944.     fputs("/onepixel 3 string store\n", outfile);
  945.  
  946.     fputs("/drawcolormappedimage {\n", outfile);
  947.  
  948.     fputs("  systemdict /colorimage known userdict /colorimage known or not {\n", outfile);
  949.     fputs("    %% convert colors to greyscale\n", outfile);
  950.     fprintf(outfile,"    /ncolors %d store\n", image->numcells);
  951.     fputs("    /ridx 0 store\n", outfile);
  952.     fputs("    /greys ncolors string def\n", outfile);
  953.     fputs("    /linecount 0 store\n", outfile);
  954.     fputs("    0 1 ncolors 1 sub {\n", outfile);
  955.     fputs("      /gidx exch store\n", outfile);
  956.     fputs("      rgbmap ridx get .3 mul\n", outfile);
  957.     fputs("      rgbmap ridx 1 add get .59 mul add\n", outfile);
  958.     fputs("      rgbmap ridx 2 add get .11 mul add\n", outfile);
  959.     fputs("      cvi\n", outfile);
  960.     fputs("      /agrey exch store\n", outfile);
  961.     fputs("      greys gidx agrey put\n", outfile);
  962.     fputs("      /ridx ridx 3 add store\n", outfile);
  963.     fputs("    } for\n", outfile);
  964.  
  965.  
  966.     fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  967.     if (landscape)
  968.       fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  969.     else
  970.       fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  971.                                                 ximage->height);
  972.  
  973.     fputs("    %% define a block of code to read and decode the input stream\n", outfile);
  974.     if (binary) {
  975.       fputs("    { currentfile read not { 0 } if\n", outfile);
  976.       fputs("      greys exch 1 getinterval ", outfile);
  977.     }
  978.     else {
  979.       fputs("    { currentfile line readhexstring pop pop\n", outfile);
  980.       fprintf(outfile, "      0 1 %d { dup\n", ximage->width-1);
  981.       fputs("        line exch get greys exch get\n", outfile);
  982.       fputs("        line 3 1 roll put\n", outfile);
  983.       fputs("      } for\n", outfile);
  984.       fputs("      line\n", outfile);
  985.     }
  986.     fputs("    } image\n\n", outfile);
  987.  
  988.     fputs("  } {  %% ifelse\n", outfile);
  989.     fputs("\n", outfile);
  990.  
  991.     fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  992.     if (landscape)
  993.       fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  994.     else
  995.       fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  996.                                                 ximage->height);
  997.  
  998.     fputs("    %% define a block of code to read and decode the input stream\n", outfile);
  999.     if (binary) {
  1000.       fputs("    { rgbmap   currentfile read not { 0 } if   3 mul 3 getinterval \n", outfile);
  1001.     }
  1002.     else {
  1003.       fputs("    { currentfile buffer readhexstring pop pop\n", outfile);
  1004.       fputs("      rgbmap buffer 0 get 3 mul 3 getinterval   %% color bytes\n", outfile);
  1005.     }
  1006.     fputs("    }\n", outfile);
  1007.     fputs("    false 3 colorimage\n", outfile);
  1008.     fputs("  } ifelse\n", outfile);
  1009.     fputs("} bind def\n", outfile);
  1010.     fprintf(outfile, "\n\n\n");
  1011.  
  1012.   }
  1013.  
  1014.  
  1015.   /* write the rgb map */
  1016.   fputs("%% get the rgb map\n", outfile);
  1017.   fputs("currentfile rgbmap readhexstring\n", outfile);
  1018.   for (x=0; x<image->numcells; x++)
  1019.     fprintf(outfile, "%02.2x%02.2x%02.2x\n",
  1020.                       (byte)((image->red[x]   >> 8) & 0xff),
  1021.               (byte)((image->green[x] >> 8) & 0xff),
  1022.               (byte)((image->blue[x]  >> 8) & 0xff) );
  1023.   fputs("pop pop\n\n", outfile);
  1024.  
  1025.  
  1026.   if (binary)
  1027.     fprintf(outfile,"%%%%BeginBinary: %d\n",
  1028.         encode ? rletotal+22+rletotal/IMAGE_CODEWIDTH
  1029.         : ximage->height*ximage->width+22+
  1030.           (ximage->height*ximage->width)/IMAGE_CODEWIDTH);
  1031.  
  1032.   fputs("drawcolormappedimage\n", outfile);
  1033.  
  1034.   /* write the map indexes */
  1035.   rletotal = 0;
  1036.   rlecount = 0;
  1037.   firstSample = TRUE;
  1038.   widthcount = 0;
  1039.   for (y=0; y<ximage->height; y++) {
  1040.     for (x=0, ptr=(byte *)(ximage->data+(y * ximage->bytes_per_line));
  1041.         x<ximage->width;
  1042.         x+=spb, ptr++) {
  1043.       b = *ptr;
  1044.       if (encode) {
  1045.         if (firstSample || b != rlesample || rlecount==254) {
  1046.       if (!firstSample) {
  1047.         if (binary) {
  1048.           putc((byte)rlecount,outfile);
  1049.           putc((byte)rlesample,outfile);
  1050.           widthcount += 2;
  1051.         }
  1052.         else {
  1053.           fprintf(outfile, "%02.2x%02.2x", rlecount, rlesample);
  1054.           widthcount += 4;
  1055.         }
  1056.         rletotal += 2;
  1057.         if (widthcount >= IMAGE_CODEWIDTH) {
  1058.           fputc('\n', outfile);
  1059.           widthcount = 0;
  1060.         }
  1061.       }
  1062.       else
  1063.         firstSample = FALSE;
  1064.       rlecount = 0;
  1065.       rlesample = b;
  1066.         }
  1067.         else
  1068.       rlecount++;
  1069.       }
  1070.       else {
  1071.     if (binary) {
  1072.       /* no width wrapping for non-encoded binary */
  1073.       fputc((byte)b,outfile);
  1074.     }
  1075.     else {
  1076.       fprintf(outfile, "%02.2x", b & 0xFF);
  1077.       widthcount += 2;
  1078.       if (widthcount >= IMAGE_CODEWIDTH) {
  1079.         fputc('\n', outfile);
  1080.         widthcount = 0;
  1081.       }
  1082.     }
  1083.       }
  1084.     }
  1085.   }
  1086.  
  1087.   if (encode) {
  1088.     if (!firstSample) {
  1089.       if (binary) {
  1090.     fputc((byte)rlecount,outfile);
  1091.     fputc((byte)rlesample,outfile);
  1092.       }
  1093.       else
  1094.         fprintf(outfile, "%02.2x%02.2x\n", rlecount, rlesample);
  1095.       rletotal += 2;
  1096.     }
  1097.   }
  1098.   else
  1099.     fputc('\n', outfile);
  1100.   if (binary)
  1101.     fprintf(outfile,"\n%%%%EndBinary\n");
  1102.  
  1103.   /* print some statistics */
  1104.   if (encode) {
  1105.     fputs("\n%\n", outfile);
  1106.     fprintf(outfile, "%% Run-length encoding savings = %5.1f%%\n",
  1107.           100.0 - ((float)(rletotal) * 100.0 / (float)(ximage->height * bpl)));
  1108.   }
  1109.  
  1110.   fputs("\n%\n", outfile);
  1111.   fputs("\ngrestore\nshowpage\n%%Trailer\n", outfile);
  1112. }
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124. /*
  1125.  * Write an image in 'puzzle' format, suitable for loading with
  1126.  * "puzzle -picture".
  1127.  */
  1128. writePuzzle(image, outfile)
  1129.   imageInfo *image;
  1130.   FILE *outfile;
  1131. {
  1132.   XImage *ximage = image->ximage;
  1133.   int nc, width, height, w, h, cidx;
  1134.   dw swaptest = 1;
  1135.  
  1136.   if (verbose)
  1137.     fprintf(stderr, "%s: formatting Puzzle output\n", programName);
  1138.  
  1139.   if (ximage->depth > 8) {
  1140.     fprintf(stderr, "%s: Puzzle converter can't handle depth > 8 yet\n",
  1141.             programName);
  1142.     return;
  1143.   }
  1144.  
  1145.   nc     = image->numcells;
  1146.   width  = ximage->width;
  1147.   height = ximage->height;
  1148.   if (*(char *)&swaptest) {
  1149.     swapbytes(&width);
  1150.     swapbytes(&height);
  1151.   }
  1152.   fwrite(&width, 4, 1, outfile);
  1153.   fwrite(&height, 4, 1, outfile);
  1154.   fputc(nc, outfile);
  1155.   for (cidx=0; cidx<nc; cidx++) {
  1156.     fputc(image->red[cidx]>>8,   outfile);
  1157.     fputc(image->green[cidx]>>8, outfile);
  1158.     fputc(image->blue[cidx]>>8,  outfile);
  1159.   }
  1160.   for (h=0; h<ximage->height; h++)
  1161.     if (ximage->bits_per_pixel == 8)
  1162.       fwrite(ximage->data+(h*ximage->bytes_per_line),ximage->width,1,outfile);
  1163.     else
  1164.       /* this won't work if depth > 8 */
  1165.       for (w=0; w<ximage->width; w++)
  1166.         fputc(XGetPixel(ximage, w, h), outfile);
  1167. }
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175. writeXWD(image, outfile, xyformat)
  1176.   imageInfo *image;
  1177.   FILE *outfile;
  1178.   int xyformat;
  1179. {
  1180.   XImage   *ximage = image->ximage;
  1181.   XWDFileHeader header;
  1182.   Visual   *visual = DefaultVisual(hDisplay, hScreen);
  1183.   XColor    color;
  1184.   dw        visMask = (visual->red_mask
  1185.                       | visual->green_mask
  1186.                       | visual->blue_mask);
  1187.   dw        swaptest = 1;
  1188.   int       i, x, y, size;
  1189.   byte      *ptr;
  1190.   int        XYtoZ;
  1191.   byte        b;
  1192.   int        bc;
  1193.  
  1194.   if (verbose)
  1195.     fprintf(stderr, "%s: formatting xwd output\n", programName);
  1196.  
  1197.   header.header_size    = (CARD32)(sizeof(header)+strlen(imageName)+1);
  1198.   header.file_version   = (CARD32) XWD_FILE_VERSION;
  1199.   XYtoZ = (ximage->depth==1 && !xyformat);
  1200.   header.pixmap_format  = (CARD32)(ximage->depth>1? ZPixmap : (xyformat? XYPixmap : ZPixmap));
  1201.   header.pixmap_depth   = (CARD32) (XYtoZ? 8 : ximage->depth);
  1202.   header.pixmap_width   = (CARD32) ximage->width;
  1203.   header.pixmap_height  = (CARD32) ximage->height;
  1204.   header.xoffset        = (CARD32) ximage->xoffset;
  1205.   header.byte_order     = (CARD32) ximage->byte_order;
  1206.   header.bitmap_unit    = (CARD32) (XYtoZ ? 8 : ximage->bitmap_unit);
  1207.   header.bitmap_bit_order = (CARD32) (XYtoZ ? MSBFirst : ximage->bitmap_bit_order);
  1208.   size = XYtoZ ? ximage->bitmap_pad * 8 : ximage->bitmap_pad;
  1209.   header.bitmap_pad     = (CARD32) size;
  1210.   header.bits_per_pixel = (CARD32) XYtoZ? 8 : ximage->bits_per_pixel;
  1211.   size = XYtoZ? ximage->width : ximage->bytes_per_line;
  1212.   header.bytes_per_line = (CARD32)size;
  1213.   header.visual_class   = (CARD32)visual->class;
  1214.   header.red_mask       = (CARD32)visual->red_mask;
  1215.   header.green_mask     = (CARD32)visual->green_mask;
  1216.   header.blue_mask      = (CARD32)visual->blue_mask;
  1217.   header.bits_per_rgb   = (CARD32)visual->bits_per_rgb;
  1218.   header.colormap_entries = (CARD32)visual->map_entries;
  1219.   /* ncolors should be image->numcells, but some programs seem to expect
  1220.    * that it is == colormap_entries.  sigh */
  1221.   header.ncolors        = header.colormap_entries;
  1222.   header.window_width   = (CARD32)ximage->width;
  1223.   header.window_height  = (CARD32)ximage->height;
  1224.   header.window_x       = 0;
  1225.   header.window_y       = 0;
  1226.   header.window_bdrwidth = 0;
  1227.  
  1228.   if (*(char *) &swaptest)
  1229.     swapdws(&header, sizeof(header));
  1230.  
  1231.   fwrite(&header, sizeof(header), 1, outfile);
  1232.   fwrite(imageName, 1, strlen(imageName)+1, outfile);
  1233.  
  1234.   if (*(char *) &swaptest)
  1235.     swapdws(&header, sizeof(header));
  1236.  
  1237.   for (i=0; i<image->numcells; i++) {
  1238.     color.pixel = i;
  1239.     color.red   = image->red[i];
  1240.     color.green = image->green[i];
  1241.     color.blue  = image->blue[i];
  1242.     color.flags = visMask;
  1243.     color.pad   = 0;
  1244.     if (*(char *) &swaptest) {
  1245.       swapdws(&color.pixel, sizeof(color.pixel));
  1246.       swapwords(&color.red, 3 * sizeof(color.red)); /* assume g and b follow r */
  1247.     }
  1248.     fwrite(&color, sizeof(XColor), 1, outfile);
  1249.   }
  1250.  
  1251.   /* pad out with black entries */
  1252.   color.red = color.green = color.blue = 0;
  1253.   color.flags = visMask;
  1254.   color.pad = 0;
  1255.   for (i=image->numcells; i<visual->map_entries; i++) {
  1256.     color.pixel = i;
  1257.     if (*(char *) &swaptest)
  1258.       swapdws(&color.pixel, sizeof(color.pixel));
  1259.     fwrite(&color, sizeof(XColor), 1, outfile);
  1260.   }
  1261.  
  1262.   if (XYtoZ) {
  1263.     for (y = 0; y < ximage->height; y++) {
  1264.       for (x = 0; x < ximage->width; x++) {
  1265.         b = XGetPixel(ximage, x, y);
  1266.     fputc(b, outfile);
  1267.       }
  1268.     }
  1269.   }
  1270.   else {
  1271.     if (ximage->depth == 1  &&  BlackPixel(hDisplay,hScreen) == 0) {
  1272.       size = ximage->height * ximage->bytes_per_line;
  1273.       for (i=0, ptr=&ximage->data[0]; i<size; i++, ptr++)
  1274.         fputc(~(*ptr), outfile);
  1275.     }
  1276.     else
  1277.       fwrite(ximage->data, ximage->height * ximage->bytes_per_line, 1, outfile);
  1278.   }
  1279. }
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285. /*
  1286.  * Write a monochrome image out in Bitmap format.  XWriteBitmapToFile
  1287.  * requires a Pixmap as input & we'd have to invent one before we could
  1288.  * use it.
  1289.  */
  1290.  
  1291. writeXYPixmap(image, outfile)
  1292.   imageInfo *image;
  1293.   FILE *outfile;
  1294. {
  1295.   XImage *ximage = image->ximage;
  1296.   int w, h;
  1297.   byte b, *line;
  1298.   int lcount;
  1299.   int reverse = BlackPixel(hDisplay, hScreen) == 0;
  1300.   int swap    = ximage->bitmap_bit_order != LSBFirst;
  1301.  
  1302.   if (verbose)
  1303.     fprintf(stderr, "%s: formatting Bitmap output\n", programName);
  1304.  
  1305.   if (ximage->depth != 1) {
  1306.     fprintf(stderr, "%s: can't write polychrome images in XY bitmap format\n",
  1307.       programName);
  1308.     return;
  1309.   }
  1310.  
  1311.   fprintf(outfile, "#define %s_width %d\n",  imageName, ximage->width);
  1312.   fprintf(outfile, "#define %s_height %d\n", imageName, ximage->height);
  1313.   fprintf(outfile, "#define %s_x_hot 0\n",   imageName);
  1314.   fprintf(outfile, "#define %s_y_hot 0\n",   imageName);
  1315.   fprintf(outfile, "static char %s_bits[] = {\n", imageName);
  1316.   lcount = 0;
  1317.   fputs("  ", outfile);
  1318.   for (h=0; h<ximage->height; h++) {
  1319.     line = (byte *)(ximage->data + (h * ximage->bytes_per_line));
  1320.     for (w=0; w<ximage->width; w+=8) {
  1321.       b = line[w/8];
  1322.       if (reverse) b = ~b;
  1323.       if (swap)    b = swapbits(b);
  1324.       fprintf(outfile, " 0x%02x", b);
  1325.       if (h<ximage->height || w+8<ximage->width)
  1326.         fputc(',', outfile);
  1327.       lcount++;
  1328.       if (lcount >= 12) {
  1329.         fputs("\n  ", outfile);
  1330.         lcount = 0;
  1331.       }
  1332.     }
  1333.   }
  1334.   fputs("  };\n", outfile);
  1335. }
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344. /*
  1345.  * Write a color image out in Pixmap format.
  1346.  * Supported output formats are xpm1 (original xpm), xpm2  and xpm3
  1347.  */
  1348. writeZPixmap(xpmFormat, image, outfile)
  1349.   imageInfo *image;
  1350.   FILE *outfile;
  1351. {
  1352.   XImage *ximage = image->ximage;
  1353.   int nc, width, height, w, h, cidx, cpp;
  1354.   char mne[MAX_CELLS][3];
  1355.  
  1356.   if (verbose) {
  1357.     switch (xpmFormat) {
  1358.     case 3:
  1359.       fprintf(stderr, "%s: formatting XPM3 Pixmap output\n", programName);
  1360.       break;
  1361.     case 2:
  1362.       fprintf(stderr, "%s: formatting XPM2 Pixmap output\n", programName);
  1363.       break;
  1364.     default:
  1365.     case 1:
  1366.       fprintf(stderr, "%s: formatting XPM output\n", programName);
  1367.       break;
  1368.     }
  1369.   }
  1370.  
  1371.   nc  = image->numcells;
  1372.   cpp = image->numcells <= 26? 1 : 2;
  1373.   switch (xpmFormat) {
  1374.   case 3:
  1375.     fprintf(outfile, "/* XPM */\nstatic char * %s_name [] = {\n\"%d %d %d %d\",\n",
  1376.       imageName, ximage->width, ximage->height, image->numcells, cpp);
  1377.     fputs("/* pixels*/\n", outfile);
  1378.     break;
  1379.   case 2:
  1380.     fprintf(outfile, "! XPM2  \n%d %d %d %d\n", ximage->width,
  1381.       ximage->height, image->numcells, cpp);
  1382.     fputs("! pixels\n", outfile);
  1383.     break;
  1384.   case 1:
  1385.   default:
  1386.     fprintf(outfile, "#define %s_format 1\n",   imageName);
  1387.     fprintf(outfile, "#define %s_width %d\n",   imageName, ximage->width);
  1388.     fprintf(outfile, "#define %s_height %d\n",  imageName, ximage->height);
  1389.     fprintf(outfile, "#define %s_ncolors %d\n", imageName, image->numcells);
  1390.     fprintf(outfile, "#define %s_chars_per_pixel %d\n",     imageName, cpp);
  1391.     fprintf(outfile, "static char * %s_colors[] = {\n", imageName);
  1392.     break;
  1393.   }
  1394.  
  1395.   for (cidx=0; cidx<image->numcells; cidx++) {
  1396.     if (cpp > 1) {
  1397.       mne[cidx][0] = (char)(cidx / 10) + 'a';
  1398.       mne[cidx][1] = (char)(cidx % 10) + '0';
  1399.       mne[cidx][2] = '\0';
  1400.     }
  1401.     else {
  1402.       mne[cidx][0] = (char)cidx + (cidx? 'A' : ' ');
  1403.       mne[cidx][1] = '\0';
  1404.     }
  1405.     switch (xpmFormat) {
  1406.     case 3:
  1407.       fprintf(outfile, "\"%s\tc #%4.4x%4.4x%4.4x\",\n",mne[cidx],
  1408.                 image->red[cidx], image->green[cidx], image->blue[cidx]);
  1409.       break;
  1410.     case 2:
  1411.       fprintf(outfile, "%s c #%4.4x%4.4x%4.4x\n", mne[cidx],
  1412.                 image->red[cidx], image->green[cidx], image->blue[cidx]);
  1413.       break;
  1414.     default:
  1415.     case 1:
  1416.       fprintf(outfile, "\"%s\", \"#%4.4x%4.4x%4.4x\"\n", mne[cidx],
  1417.                 image->red[cidx], image->green[cidx], image->blue[cidx]);
  1418.       break;
  1419.     }
  1420.   }
  1421.   if (xpmFormat == 1) {
  1422.     fputs("} ;\n", outfile);
  1423.     fprintf(outfile, "static char * %s_pixels[] = {\n", imageName);
  1424.   }
  1425.   for (h=0; h<ximage->height; h++) {
  1426.     if (xpmFormat != 2)
  1427.       fputs("\"", outfile);
  1428.     for (w=0; w<ximage->width; w++)
  1429.       fputs(mne[XGetPixel(ximage, w, h)], outfile);
  1430.     if (xpmFormat == 2)
  1431.       fputs("\n", outfile);
  1432.     else
  1433.       fputs("\",\n", outfile);
  1434.   }
  1435.   if (xpmFormat == 3)
  1436.     fputs("};\n", outfile);
  1437.   else if (xpmFormat != 2)
  1438.     fputs("} ;\n", outfile);
  1439. }
  1440.  
  1441.  
  1442.  
  1443.  
  1444.